/*
 * Cliente.h
 *
 *  Created on: 04/10/2012
 *      Author: leandro
 */

#ifndef CLIENTE_H_
#define CLIENTE_H_

#define DELAY_CABEZA 15

#include "SDL/SDL_mixer.h"
#include "../../Vista/Vista.h"
#include "../../Modelo/Pantalla/Pantalla.h"
#include "../Socket.h"
#include "../../Controlador/InputCliente.h"
#include "../../Utils/Timer.h"
#include <sys/ioctl.h>
#include <algorithm>
#include <queue>
#include "../Sincronizador.h"

#if INSTALANDO
#define PATH_SINCRONIZACION_CLIENTE "/tmp/"
#else
#define PATH_SINCRONIZACION_CLIENTE "../Res/"
#endif

using namespace std;

#define MAXDATASIZE 100   /* El número máximo de datos en bytes */
#define TIEMPO_ENTRE_UPDATES 3000
#define TIEMPO_ENTRE_MENSAJES_CLIENT 1000
#define CLIENT_TIMEOUT 20000

typedef int ipNumber;

enum EstadoJuegoCliente {
	JuegoStart,
	JuegoEnd,
	JuegoNext
};

class Cliente {

private:

	Pantalla* pantalla;
	Vista* vista;
	SDL_Rect* rectPersonaje;
	int margenScroll;
	idImagen_t imagenFondo;
	InputCliente* controlador;
	Timer t_juego;
	string mensajes;
	
	vector< pair < pair<idImagen_t, int> , Punto> > dibujables;
	vector< pair<idImagen_t, string> > puntajes;
	queue< pair<int, string> > updates;
	vector< pair< pair<bool, int>, Punto > > sonidos;
	int numJugador;

	EstadoJuegoCliente estadoJuego;
	EstadoConexion estadoConexion;

	pthread_mutex_t mutexDibujables;
	pthread_mutex_t mutexPuntajes;
	pthread_mutex_t mutexSonidos;
	pthread_mutex_t mutexUpdates;
	pthread_mutex_t mutexEstadoJuego;
	pthread_mutex_t mutexEstadoConexion;
	
	int socket;
	int largo; // largo del contenido del socket
	
	void unSerializeObstaculos(string mensaje);
	void unSerializeDibujable(string mensaje);
	void unSerializePuntajes(string mensaje);
	void unSerializeSonidos(string mensaje);
	void unSerializeUpdate(string mensaje, char tipoMensaje);
	Sincronizador sincronizador;

public:

	Cliente();
	~Cliente();
	bool Conectar(string host, string port);
	bool sincronizar();
	void setVista(int ancho, int alto, int scroll, int anchoNivel, int altoNivel);
	void setImagenFondo(idImagen_t idImagenFondo);
	void setPersonaje(int posX, int posY, int ancho, int alto,int margen);
	void setEstadoJuego(EstadoJuegoCliente estado);
	void setEstadoConexion(EstadoConexion estado);
	
	void setPuntajes(vector< pair<int, string> > puntajes);
	void setDibujables(vector< pair < pair<idImagen_t, int> , Punto> > v_dibujables);
	void setSonidos(vector< pair<vector< pair<int, int> >, Punto> > sonidos);
	void addUpdate(string mensaje, char tipoMensaje);
	pair<int, string> getNextUpdate();
	void unSerialize(string cadena);
	
	void updatePersonaje(int posX, int posY);
	bool Comenzar(vector<infoImagen_t> infoImagenes, vector<infoSonido_t> infoSonidos, int personaje);
	void Jugar();
	
	InputCliente* getControlador();
	int getSocket();
	Uint32 getTime();
	EstadoJuegoCliente getEstadoJuego();
	EstadoConexion getEstadoConexion();
	Pantalla* getPantalla();
	int getMargenScroll();
};

void* ClienteAServidor(void* data);
void* ServidorACliente(void* data);

#endif /* CLIENTE_H_ */
